package alogrithm;

import java.util.ArrayList;

import javax.swing.JOptionPane;

import engine.Edge;
import engine.Vertex;
import gui.View;

public class Prim
{
   private ArrayList<Edge> edges;
   private int numEdges, numVertices;
   private Vertex startNode = null;
   private ArrayList<Vertex> vertices;

   public Prim(View view)
   {
      edges = view.getEdges();
      vertices = view.getVertices();
      numEdges = view.getEdges().size();
      numVertices = view.getVertices().size();

      algorithm();
      view.setAllEdgeStatusFromTo(1, 0);
      view.setAllVertexStatusFromTo(1, 0);

      for(int i=0; i<vertices.size(); i++)
         if(vertices.get(i).getStatus()!=2)
            JOptionPane.showMessageDialog(null,
                  "Please connect all unconnected nodes.");

   }

   public Prim(View view, Vertex startNode)
   {
      edges = view.getEdges();
      vertices = view.getVertices();
      numEdges = view.getEdges().size();
      numVertices = view.getVertices().size();
      this.startNode = startNode;
      algorithm();
   }

   public void algorithm()
   {
      int min = 0;
      if (startNode == null)
         startNode = vertices.get(0);

      // mark any connects edges into active mode
      startNode.setAllEdgeStatusFromTo(0, 1);
      for (int i = 0; i < numVertices; i++)
      {

         // get the minimum weight of the active
         min = getMinWeight();
         // set the current edges into a visited mode
         edges.get(min).setStatus(2); // Status 2 mean it already visited
         // set the two connected edges into visited mode
         edges.get(min).getFirstNode().setStatus(2);
         edges.get(min).getSecondNode().setStatus(2);

         edges.get(min).getSecondNode().setAllEdgeStatusFromTo(0, 1);
         edges.get(min).getFirstNode().setAllEdgeStatusFromTo(0, 1);

      }
   }

   /**
    * Find the lowest weight of the marked edge
    * 
    * @return the index of the lowest array edges
    */
   public int getMinWeight()
   {
      int max = Integer.MAX_VALUE;
      int index = 0;
      for (int i = 0; i < numEdges; i++)
         // Check if both nodes is already been visited
         if (edges.get(i).getFirstNode().getStatus() == 2
         && edges.get(i).getSecondNode().getStatus() == 2)
         {

         }
         else if ((edges.get(i).getStatus() == 1 && edges.get(i).getWeight() < max)
               && (edges.get(i).getFirstNode().getStatus() == 2 || edges.get(i)
               .getSecondNode().getStatus() == 2))
         {
            index = i;
            max = edges.get(i).getWeight();
         }

      return index;
   }

   /**
    * Mark any edges that connected the vertex as an active edge
    * 
    * @param vertex
    */
   public void markConnectEdge(Vertex vertex)
   {
      for (int i = 0; i < numEdges; i++)
         // check is the edges status is non active
         if (edges.get(i).getStatus() == 0
         && (edges.get(i).getFirstNode() == vertex || edges.get(i)
         .getSecondNode() == vertex))
            edges.get(i).setStatus(1);
   }
}
